#ifndef GAME_ANIMATION_TRUNKS_SHADER_H
#define GAME_ANIMATION_TRUNKS_SHADER_H
//
// Game Animation.
// Copyright (C) 2007 Department of Computer Science, University of Copenhagen
//
#include <animation/configuration.h>

#include <OpenTissue/gpu/cg/cg_program.h>
#include <OpenTissue/gpu/image/image.h>
#include <OpenTissue/gpu/image/io/image_read.h>
#include <OpenTissue/gpu/image/io/image_write.h>
#include <OpenTissue/gpu/texture/texture_texture2D.h>
#include <OpenTissue/gpu/image/image_make_noise.h>
#include <OpenTissue/gpu/image/image_alpha_modulation.h>

namespace animation
{

  /**
  * The Grass Shader.
  * This class setups (and shutdowns) the rendering before draw the geometry of the grass layer.
  *
  */
  class TrunksShader
  {
  protected:

    OpenTissue::cg::Program                                m_vertex_program;
    OpenTissue::cg::Program                                m_fragment_program;
    boost::shared_ptr<OpenTissue::image::Image<unsigned char> > m_image;
    OpenTissue::texture::texture2D_pointer                      m_texture;

  public:

    /**
    * Pre-rendering.
    *
    * @param rightx          The x-coordinate of the camera right vector in WCS.
    * @param righty          The y-coordinate of the camera right vector in WCS.
    * @param rightz          The z-coordinate of the camera right vector in WCS.
    * @param upx             The x-coordinate of the camera up vector in WCS.
    * @param upy             The y-coordinate of the camera up vector in WCS.
    * @param upz             The z-coordinate of the camera up vector in WCS.
    * @param time            The current time, used to animate grass movement.
    * @param visible_range   Determines how far away one can see grass clumps before the fade out into the background.
    */
    bool pre_render ( 
		bool reload
		, float time
		,float light_x,float light_y,float light_z
		,float intensity
	){
      //--- Load textures if they are not allready loaded
      if(!m_image)
      {
        m_image.reset( new OpenTissue::image::Image<unsigned char>() );
        OpenTissue::image::read(demo_path + "TheSwampThing2008/data/RedOakBark.png",*m_image);
		m_texture = m_image->create_texture(GL_RGBA);
      }

      //--- Load vertex program, note that cg-program path is currently hardcoded, a
      //--- more sensible solution would be
      //---
      //---  std::string filename = get_environment_variable("OPENTISSUE") + .... + "vp_grass.cg";
      //---
      if(!m_vertex_program.is_program_loaded()||reload)
		  if(!m_vertex_program.load_from_file(OpenTissue::cg::Program::vertex_program,demo_path + "../animation/shader/3dtree/trunks/trunks_vp.cg")){
			  return false;
		  }

	  m_vertex_program.set_float_param("time",time);
	  m_vertex_program.set_float_param("light_vec",light_x,light_y,light_z);
	  m_vertex_program.set_float_param("intensity",intensity);
      m_vertex_program.set_modelview_projection_matrix();
	  m_vertex_program.set_modelview_inverse_transpose();

      //--- load fragment program
      if(!m_fragment_program.is_program_loaded()||reload)
		  if(!m_fragment_program.load_from_file(OpenTissue::cg::Program::fragment_program,demo_path + "../animation/shader/3dtree/trunks/trunks_fp.cg")){
			  return false;
		  }

      m_fragment_program.set_input_texture("texture",m_texture);

      m_fragment_program.enable();
      m_vertex_program.enable();

      //--- Setup openGL state
      glEnable(GL_MULTISAMPLE_ARB);              //--- KE 2005.10.23: Need a ge78000:-(
      glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
      //glEnable(GL_BLEND);
      //glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
     // glEnable(GL_ALPHA_TEST);
    //  glAlphaFunc(GL_GREATER, 0);
	  return true;
    }

    void post_render()
    {
      glDisable(GL_MULTISAMPLE_ARB);             //--- KE 2005.10.23: Need a ge78000:-(
      glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
      glDisable(GL_ALPHA_TEST);
      glDisable(GL_BLEND);

      m_fragment_program.disable();
      m_vertex_program.disable();
    }
  };

} // namespace animation

// GAME_ANIMATION_GRASS_SHADER_H
#endif
